import Vue from "vue";

const Plugins = {};
Plugins.install = function (Vue) {
  Object.defineProperty(Vue.prototype, '$getFileClass', {
    value: function (fileType) {
      if ('jpg,jpeg,bmp,gif,png,tif'.indexOf(fileType) >= 0) {
        return 'file image'
      }

      if ('doc,docx,txt,rtf,wps'.indexOf(fileType) >= 0) {
        return 'file powerpoint '
      }

      if ('xls,xlsx'.indexOf(fileType) >= 0) {
        return 'file excel '
      }

      if ('ppt,pptx'.indexOf(fileType) >= 0) {
        return 'file powerpoint '
      }

      if ('pdf'.indexOf(fileType) >= 0) {
        return 'file pdf '
      }

      if ('zip,rar,7z'.indexOf(fileType) >= 0) {
        return 'file archive '
      }

      if ('dwg,dws,dwt,dxf'.indexOf(fileType) >= 0) {
        return 'file alternate '
      }

      return ''
    }
  })
  /** 时间格式化
   * @param date 待格式化的 时间字符串 或 Date对象
   * @param fmt {String} 时间格式 如 yyyy-MM-dd
   */
  Object.defineProperty(Vue.prototype, "$date", {
    value: function dateFtt(date, fmt = "yyyy-MM-dd hh:mm:ss") {
      //author: meizz
      if (!date) {
        return "";
      }
      if (typeof date === "string") {
        date = date.replace(/-/g, "/"); //手机端浏览器需将 - 替换为 /
      }
      //兼容字符串模式和时间戳,字符格式如: 2018-08-01
      if (typeof date !== "object") {
        date = new Date(date);
      }

      let o = {
        "M+": date.getMonth() + 1, //月份
        "d+": date.getDate(), //日
        "h+": date.getHours(), //小时
        "m+": date.getMinutes(), //分
        "s+": date.getSeconds(), //秒
        "q+": Math.floor((date.getMonth() + 3) / 3), //季度
        S: date.getMilliseconds(), //毫秒
      };
      if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
      for (let k in o)
        if (new RegExp("(" + k + ")").test(fmt))
          fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
      return fmt;
    },
  });
  /**
   * 判断变量是否为日期。
   *
   * @param o 变量
   * @returns {Boolean} 是否为日期：
   * <ol>
   *    <li>true-是；</li>
   *    <li>false-否。</li>
   * </ol>
   */
  Object.defineProperty(Vue.prototype, "$isDate", {
    value: (o) => {
      try {
        return Object.prototype.toString.call(o) === "[object Date]";
      } catch (e) {
        console.error(e.message);

        return false;
      }
    },
  });
  function padLeftZero(str) {
    return ("00" + str).substr(str.length);
  }
  Object.defineProperty(Vue.prototype, "$formatDate", {
    value: (date, fmt) => {
      if (!date) return;
      date = new Date(+date); //支持直接传入时间戳()
      if (/(y+)/.test(fmt)) {
        fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
      }
      let o = {
        "M+": date.getMonth() + 1,
        "d+": date.getDate(),
        "H+": date.getHours(),
        "m+": date.getMinutes(),
        "s+": date.getSeconds(),
      };
      for (let k in o) {
        let str = o[k] + "";
        if (new RegExp(`(${k})`).test(fmt)) {
          fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? str : padLeftZero(str));
        }
      }
      return fmt;
    },
  });
  /**
   * 获取开始时间和结束时间。
   *
   * @param endTime 结束时间
   * @param hours 小时数（数字，如：2, 4, 6, 8, 10, 12, 24 等）
   * @param fmt 时间格式
   * @return {Number} 动态处理大数字
   */
  Object.defineProperty(Vue.prototype, "$getStartAndEndTimeByEndTime", {
    value: (endTime, hours, fmt = "yyyy-MM-dd hh:mm:ss") => {
      let endTime2;

      if (Vue.prototype.$isDate(endTime)) {
        endTime2 = endTime;
      } else {
        try {
          endTime2 = new Date(endTime);
        } catch (e) {
          throw new Error("时间格式错误");
        }
      }

      // 创建开始时间
      const startTime = new Date(endTime2.getTime());
      startTime.setHours(endTime2.getHours() - Vue.prototype.$getNumber(hours));

      return {
        startTime: Vue.prototype.$date(startTime, fmt),
        endTime: Vue.prototype.$date(endTime2, fmt),
      };
    },
  });
  /**
   * 获取开始时间和结束时间。
   *
   * @param endTime 结束时间
   * @param hours 小时数（数字，如：2, 4, 6, 8, 10, 12, 24 等）
   * @param fmt 时间格式
   * @return {Number} 动态处理大数字
   */
  Object.defineProperty(Vue.prototype, "$getStartAndEndTimeByStartTime", {
    value: (startTime, hours, fmt = "yyyy-MM-dd hh:mm:ss") => {
      let startTime2;

      if (Vue.prototype.$isDate(startTime)) {
        startTime2 = startTime;
      } else {
        try {
          startTime2 = new Date(startTime);
        } catch (e) {
          throw new Error("时间格式错误");
        }
      }

      // 创建结束时间
      const endTime = new Date(startTime2.getTime());
      endTime.setHours(startTime2.getHours() + Vue.prototype.$getNumber(hours));

      return {
        startTime: Vue.prototype.$date(startTime2, fmt),
        endTime: Vue.prototype.$date(endTime, fmt),
      };
    },
  });
  /**
   * 获取当日开始时间和结束时间
   */
  Object.defineProperty(Vue.prototype, "$timeScopeToday", {
    value: (fmt = "yyyy-MM-dd hh:mm:ss") => {
      return [
        Vue.prototype.$date(new Date(new Date().toLocaleDateString()), fmt),
        Vue.prototype.$date(new Date(), fmt),
        "today",
      ];
    },
  });
  /**
   * 最近一周日期范围
   * 注意这里虽然叫thisWeek但是取的是整个最近一周，完整的7天
   */
  Object.defineProperty(Vue.prototype, "$timeScopeThisWeek", {
    value: () => {
      return [
        Vue.prototype.$getDateCycleBeginEnd(6, "yyyy-MM-dd hh:mm:ss")[0],
        Vue.prototype.$date(new Date(), "yyyy-MM-dd hh:mm:ss"),
        "thisWeek",
      ];
    },
  });

  /**
   * 本月日期范围，从本月1号到今天
   */
  Object.defineProperty(Vue.prototype, "$timeScopeThisMonth", {
    value: () => {
      return [
        Vue.prototype.$date(new Date(), "yyyy-MM-01 00:00:00"),
        Vue.prototype.$date(new Date(), "yyyy-MM-dd hh:mm:ss"),
        "thisMonth",
      ];
    },
  });
  /**
   * 最近一个月，30天日期范围不包含今天
   */
  Object.defineProperty(Vue.prototype, "$timeScopeThirtyDaysNoToday", {
    value: () => {
      return [
        Vue.prototype.$getDateCycleBeginEnd(31, "yyyy-MM-dd hh:mm")[0],
        Vue.prototype.$getDateCycleBeginEnd(1, "yyyy-MM-dd hh:mm")[0],
        "thirtyDays",
      ];
    },
  });
  /**
   * 获取现在时间前后几个月的月份的开始时间和结束时间,
   * @param num 月份数（数字，如：-1, -2, 1, 2, 4, 6, 8, 10, 12, 24 等）,为负数时是过去几个月，正数为往后几个月
   */
  Object.defineProperty(Vue.prototype, "$getMonthInfo", {
    value: (num, date) => {
      //起止日期数组

      let startStop = new Array();

      //当前时间
      let currentDate = date ? new Date(date) : new Date();
      let month = currentDate.getMonth() + num;

      if (month < 0) {
        let n = parseInt(-month / 12);

        month += n * 12;

        currentDate.setFullYear(currentDate.getFullYear() - n);
      }

      currentDate = new Date(currentDate.setMonth(month));

      //获得当前月份0-11

      let currentMonth = currentDate.getMonth();

      //获得当前年份4位年

      let currentYear = currentDate.getFullYear();

      //获得上一个月的第一天

      let currentMonthFirstDay = new Date(currentYear, currentMonth, 1);

      //获得上一月的最后一天

      let currentMonthLastDay = new Date(currentYear, currentMonth + 1, 0);

      startStop.push(Vue.prototype.$date(new Date(currentMonthFirstDay), "yyyy-MM-dd hh:mm:ss"));

      startStop.push(Vue.prototype.$date(new Date(currentMonthLastDay), "yyyy-MM-dd 23:59:59"));

      return startStop;
    },
  });
  /**
   * 以当前时刻为基准，获取最近days天的时间节点范围，精确到秒
   * @param days
   * @param fmt
   * @returns {Date[]}
   */
  Object.defineProperty(Vue.prototype, "$getDateCycleBeginEnd", {
    value: (days, fmt = "yyyy-MM-dd hh:mm:ss") => {
      let end = new Date();
      let start = new Date();

      if (!isNaN(days)) {
        start.setTime(start.getTime() - days * 24 * 3600 * 1000);

        start = Vue.prototype.$date(start, fmt);
        end = Vue.prototype.$date(end, fmt);

        if (days > 0) {
          return [start, end];
        } else {
          return [end, start];
        }
      }

      return [start, end];
    },
  });
  /**
   * 获取安全的数字。
   *
   * @param num 数字
   * @return {Number} 安全的数字
   */
  Object.defineProperty(Vue.prototype, "$getNumber", {
    value: (num) => {
      return Vue.prototype.$isNumber(num) ? num : Vue.prototype.$isNumberStr(num) ? Number(num) : 0;
    },
  });
  /**
   * 判断变量是否为数字。
   *
   * @param o 变量
   * @returns {Boolean} 是否为数字：
   * <ol>
   *    <li>true-是；</li>
   *    <li>false-否。</li>
   * </ol>
   */
  Object.defineProperty(Vue.prototype, "$isNumber", {
    value: (o) => {
      try {
        return Object.prototype.toString.call(o) === "[object Number]";
      } catch (e) {
        console.error(e.message);

        return false;
      }
    },
  });
  /**
   * 判断变量是否为数字字符串。
   *
   * @param o 变量
   * @returns {Boolean} 是否为数字字符串：
   * <ol>
   *    <li>true-是；</li>
   *    <li>false-否。</li>
   * </ol>
   */
  Object.defineProperty(Vue.prototype, "$isNumberStr", {
    value: (o) => {
      try {
        let numReg = /^(\+|-)?[0-9]+(\.[0-9]+)?$/;

        return numReg.test(Vue.prototype.$getString(o));
      } catch (e) {
        console.error(e.message);

        return false;
      }
    },
  });
  /**
   * 获取安全的字符串。
   *
   * @param str 字符串
   * @return {String} 安全的字符串
   */
  Object.defineProperty(Vue.prototype, "$getString", {
    value: (str) => {
      let trimReg = /(^\s*)|(\s*$)/g;

      return Vue.prototype.$isBlank(str) ? "" : String(str).replace(trimReg, "");
    },
  });
  /**
   * 字符串为空。
   *
   * @param str 字符串
   * @returns {Boolean} 是否为空：
   * <ol>
   *    <li>true-为空；</li>
   *    <li>false-不为空。</li>
   * </ol>
   */
  Object.defineProperty(Vue.prototype, "$isBlank", {
    value: (str) => {
      try {
        if (Vue.prototype.$isNull(str)) {
          return true;
        } else if (!Vue.prototype.$isString(str)) {
          return false;
        }

        let trimReg = /(^\s*)|(\s*$)/g;
        let str1 = str.replace(trimReg, "");

        if (str1.length) {
          return false;
        }

        return true;
      } catch (e) {
        console.error(e.message);

        return true;
      }
    },
  });
  /**
   * 判断对象是否为空。
   *
   * @param o 对象
   * @returns {Boolean} 是否为空：
   * <ol>
   *    <li>true-为空；</li>
   *    <li>false-不为空。</li>
   * </ol>
   */
  Object.defineProperty(Vue.prototype, "$isNull", {
    value: (o) => {
      try {
        return (
          Object.prototype.toString.call(o) === "[object Undefined]" ||
          Object.prototype.toString.call(o) === "[object Null]"
        );
      } catch (e) {
        console.error(e.message);

        return true;
      }
    },
  });
  /**
   * 判断变量是否为字符串。
   *
   * @param o 变量
   * @returns {Boolean} 是否为字符串：
   * <ol>
   *    <li>true-是；</li>
   *    <li>false-否。</li>
   * </ol>
   */
  Object.defineProperty(Vue.prototype, "$isString", {
    value: (o) => {
      try {
        return Object.prototype.toString.call(o) === "[object String]";
      } catch (e) {
        console.error(e.message);

        return false;
      }
    },
  });
};

Vue.use(Plugins);
export default Plugins;
